#include "weather_client.h"
#include "FreeRTOS.h"
#include "task.h"

#include "lwip/sockets.h"
#include "lwip/api.h"
#include "lwip/sys.h"
#include "lwip/inet.h"


#define SEND_BUF_SIZE   256
#define RECV_BUF_SIZE   1024*7
/**
 * http 请求报文
 */
#define HTTPC_REQ_11_PROXY_PORT \
        "GET http://%s:%d/%s HTTP/1.0\r\n" /* HOST, host-port, URI */               \
        "User-Agent: %s\r\n"              /* User-Agent */                         \
        "Accept: */*\r\n"                                                          \
        "Host: %s\r\n"          /* server name */                                  \
        "Connection: Close\r\n" /* we don't support persistent connections, yet */ \
        "\r\n"


static int create_request_string(const char* host,
    int port,
    const char* uri,
    char* buf, size_t buf_size) {
    return snprintf(buf, buf_size, HTTPC_REQ_11_PROXY_PORT, host, port, uri, "lwip client", host);
}

void http_weather_task(void* argv)
{
    ip_addr_t dns_ip;
    struct sockaddr_in client_addr;
    err_t ret;
    int sock = -1;
    char* host_ip;
    int len = -1;
    int try_count = 0;
    int sum_len = 0;

    char tmp[32];
    char send_buf[SEND_BUF_SIZE];
    char* recv_buf;

    recv_buf = pvPortMalloc(RECV_BUF_SIZE);
    memset(tmp, '\0', sizeof(tmp));
    memset(send_buf, '\0', sizeof(send_buf));
    memset(recv_buf, '\0', sizeof(recv_buf));

    printf("request task start\n\n");
    //根据服务器域名获取ip
    ret = netconn_gethostbyname(HTTP_HOST, &dns_ip);
    if (ERR_OK != ret) {
        printf("get host ip error\n");
    }
    //把int32类型的ip转换成十进制点分ip
    host_ip = ip_ntoa(&dns_ip);
    printf("host name: %s, ip: %s\n", HTTP_HOST, host_ip);
    while (1)
    {
        if (try_count > 3) {
            goto end;
        }
        //创建socket
        sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock < 0)
        {
            printf("socket cerate error: %d\n", sock);
            vTaskDelay(10);
            try_count++;
            continue;
        }
        //初始化client
        memset(&client_addr, 0, sizeof(struct sockaddr_in));
        //设置socket为ip4协议
        client_addr.sin_family = AF_INET;
        //把"127.0.0.1"点分十进制ip转换成32位的int整数格式
        client_addr.sin_addr.s_addr = dns_ip.addr;
        //设置端口号
        client_addr.sin_port = htons(PORT);
        //开始连接socket
        if (connect(sock,
            (struct sockaddr*)&client_addr,
            sizeof(client_addr)) != 0) {
            printf("connect failed!\n");
            closesocket(sock);
            vTaskDelay(10);
            try_count++;
            continue;
        }
        printf("connect successful!\n");
        //创建请求数据
        len = create_request_string(HTTP_HOST, PORT, HTTP_PATH, send_buf, SEND_BUF_SIZE);
        //向socket写入请求数据
        write(sock, send_buf, len);
        printf("request header:\r\n\r\n%s\r\n", send_buf);
        len = -1;
        do {
            /**
             * 每次读取32个字节放入tmp中，不一定够32字节
             * 所以用返回值表示读取的字节数
             * 如果返回0说明读完了，如果返回-1说明出现异常(读完了继续读也是 返回-1)
             */
            len = recv(sock, tmp, 32, 0);
            //计算一共读了多少字节
            sum_len += len;
            if (len < 0) {
                printf("recv error: %d\n", len);
                break;
            }
            if (0 == len) {
                printf("receive successful!\n");
                break;
            }
            /**
             * 从接收的tmp数组中复制len个字节到recv_buf中
             * 起始地址+已经读的字节就是需要拼接的地方
             * 最后可能只读了1个字节，其余的字节都是之前读的旧数据
             * 所以读了多少字节就复制多少字节，不能全部复制
             */
            strncat(recv_buf, tmp, len);
        } while (1);

        if (NULL != argv) {
            callback* fun = (callback*)argv;
            fun(recv_buf);
        }

    end:
        closesocket(sock);
        vTaskDelay(1000);
        vTaskDelete(NULL);
    }
    vTaskDelete(NULL);
}
